package cc.rengu.igas.opms.core.service.trans.common;

import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.core.service.base.ManageService;
import cc.rengu.igas.opms.facade.base.BaseResponse;
import cc.rengu.igas.opms.facade.request.GetCouponRequest;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.UserSessionConstant;
import cc.rengu.igas.share.core.realize.UserService;
import cc.rengu.igas.share.core.realize.impl.UserServiceImpl;
import cc.rengu.igas.share.core.service.channel.momp.ClaimCouponService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.BizStatusEnum;
import cc.rengu.oltp.service.common.enums.CheckResultEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.utility.util.*;
import org.apache.commons.codec.binary.Base64;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;

/**
 * 优惠劵领取
 * 要求用户支付成功后仅可领取一次优惠券
 * 领取优惠券时 非微信支付宝的交易使用用户的手机号进行领取、微信支付宝的交易使用openid
 *
 * @author keyi
 * @modify by wangcheng
 * @date 2020/4/26.
 */
public class GetCouponService extends ManageService implements TransCustomImpl {
    @Override
    protected Object bizBeforeCust() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        GetCouponRequest getCouponRequest = new GetCouponRequest();
        ConvertUtil.convertOutput(getCouponRequest);
        if ("1".equals(getCouponRequest.getUserType()) || "2".equals(getCouponRequest.getUserType())) {
            /* 微信支付宝扫码特殊处理，先解密userId然后再Base64解码*/
            if (!StringUtil.isEmptyOrNull(getCouponRequest.getUserId())) {
                UserService userService = new UserServiceImpl();
                String sensitiveKey = userService.getUserSessionValue(UserSessionConstant.SENSITIVE_KEY);
                if (StringUtil.isEmptyOrNull(sensitiveKey)) {
                    rglog.info("用户会话敏感信息密钥不存在,不对微信或支付宝用户标识进行解密处理!");
                    return getCouponRequest;
                }
                String decryUserId = AESUtil.pkcs7CbcDecryptData(Base64.decodeBase64(sensitiveKey), Base64.decodeBase64(getCouponRequest.getUserId()));
                rglog.debug("微信支付宝解密后的userId:<{}>", decryUserId);
                String userId = new String(Base64.decodeBase64(decryUserId.getBytes(StandardCharsets.UTF_8)));
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.USER_ID, userId);
                getCouponRequest.setUserId(userId);
            }
        }
        return getCouponRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        GetCouponRequest getCouponRequest = (GetCouponRequest) request;
        String instId = getCouponRequest.getHeader().getInstId();
        String userOrderId = getCouponRequest.getUserOrderId();

        //step1.校验原订单是否支付成功
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByUserOrderId(instId, userOrderId);
        if (null == userOrderInfo) {
            rglog.info("用户支付订单不存在");
            throw new BizException(RespCodeEnum.ORDER_NOEXIT.getRespCode(), RespCodeEnum.ORDER_NOEXIT.getRespDesc());
        } else if (!TransStatusEnum.TRANS_SUCC.getStatus().equals(userOrderInfo.getTransStatus()) ||
                !BizStatusEnum.FINISH.getStatus().equals(userOrderInfo.getBizStatus())) {
            rglog.info("用户订单表业务状态或交易状态不是成功，bizStatus:<{}>,transStatus:<{}>", userOrderInfo.getBizStatus(), userOrderInfo.getTransStatus());
            throw new BizException(RespCodeEnum.ORDER_STATUS_ERR.getRespCode(), RespCodeEnum.ORDER_STATUS_ERR.getRespDesc());
        }

        //判断领取的用户是否与用户订单表的用户一致
        if (StringUtil.isEmptyOrNull(getCouponRequest.getUserId())) {
            rglog.info("未上送用户信息");
            throw new BizException(RespCodeEnum.USER_INFO_MISMATCH.getRespCode(), RespCodeEnum.USER_INFO_MISMATCH.getRespDesc());
        } else if (!getCouponRequest.getUserId().equals(userOrderInfo.getUserId())) {
            rglog.info("领取优惠券的userId:<{}>和用户订单表的userId:<{}>不一致", userOrderInfo.getUserId(), getCouponRequest.getUserId());
            throw new BizException(RespCodeEnum.USER_INFO_MISMATCH.getRespCode(), RespCodeEnum.USER_INFO_MISMATCH.getRespDesc());
        }

        //校验用户是否已领取优惠劵,用户支付成功后会设置一个缓存信息
        String key = OpmsParamConstant.GET_COUPON_TOKEN_KEY + getCouponRequest.getHeader().getSession();
        rglog.info("领取优惠券标识的key:<{}>", key);
        String isGetCoupon = RedisUtil.onceGet(key);
        rglog.info("用户是否已经领取优惠券:<{}>", isGetCoupon);
        if (StringUtil.isEmptyOrNull(isGetCoupon) || !AppParamConstant.YES.equals(isGetCoupon)) {
            rglog.info("用户已经领取过一次优惠劵信息");
            throw new BizException(RespCodeEnum.USER_REGET_COUPON.getRespCode(), RespCodeEnum.USER_REGET_COUPON.getRespDesc());
        }
        //重置缓存信息
        RedisUtil.onceDel(key);

        //step2.调用营销领取卡劵
        ClaimCouponService claimCouponService = new ClaimCouponService();
        claimCouponService.callService(txnInfo, null, ShareParamConstant.CALL_CFG_DEFAULT_BIZ_SCENE, getCouponRequest);

        //构建应答信息
        BizResponse<BaseResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        Optional<ChannelCallCfg> channelCallCfgOpt = channelCallCfgList.stream().filter(item ->
                item.getBizScene().equals(ShareParamConstant.CALL_CFG_DEFAULT_BIZ_SCENE)).findFirst();
        return channelCallCfgOpt.orElse(null);
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return CheckResultEnum.PASSED;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        return transStatusEnum;
    }
}
